package bev.query;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.EnumSet;
import java.util.Vector;

import bev.ConnectionManager;
import bev.article.ArticleType;

// This item is populated with information on how a query should be performed
// and provides a method to run the query once it has been configured.
public class ArticleQuery {
    EnumSet<ArticleType> articleTypes;
    String queryString;
    
    // Creates an ArticleQuery object based on an input string to search.
    public ArticleQuery( String queryString ) {
        this.queryString = queryString;
    }
    
    // Runs the query logic outlines by this ArticleQuery object
    // and returns a Vector of ArticleListItems matching the query.
    public Vector<ArticleListItem> runQuery() {
        if ( queryString == null )
            queryString = "";
        
        System.out.printf( "Running query: '%s'\n", queryString );
        
        // Query the database and build a Vector of ArticleListItems
        // that are used to display article names in the search list.
        Vector<ArticleListItem> listItems = new Vector<ArticleListItem>();
        
        try {
            // Run query on people.
            {
                ResultSet rs = ConnectionManager.RunSQLQuery( "SELECT id, name FROM people" );
                while ( rs.next() ) {
                    String person_name = rs.getString( "name" );
                    
                    if ( searchArticleField( queryString, person_name ) ) {
                        int person_id = rs.getInt( "id" );
                        ArticleListItem listItem = new ArticleListItem( ArticleType.PERSON, person_id, person_name );
                        listItems.add( listItem );
                    }
                }
                ConnectionManager.closeConnection();
            }
            
            // Run query on places.
            {
                ResultSet rs = ConnectionManager.RunSQLQuery( "SELECT id, name FROM places" );
                while ( rs.next() ) {
                    String place_name = rs.getString( "name" );
                    
                    if ( searchArticleField( queryString, place_name ) ) {
                        int place_id = rs.getInt( "id" );
                        ArticleListItem listItem = new ArticleListItem( ArticleType.PLACE, place_id, place_name );
                        listItems.add( listItem );
                    }
                }
                ConnectionManager.closeConnection();
            }
            
            // Run query on events.
            {
                ResultSet rs = ConnectionManager.RunSQLQuery( "SELECT id, name FROM events" );
                while ( rs.next() ) {
                    String event_name = rs.getString( "name" );
                    
                    if ( searchArticleField( queryString, event_name ) ) {
                        int event_id = rs.getInt( "id" );
                        ArticleListItem listItem = new ArticleListItem( ArticleType.EVENT, event_id, event_name );
                        listItems.add( listItem );
                    }
                }
                ConnectionManager.closeConnection();
            }
            
            // Run query on objects.
            {
                ResultSet rs = ConnectionManager.RunSQLQuery( "SELECT id, name FROM objects" );
                while ( rs.next() ) {
                    String object_name = rs.getString( "name" );
                    
                    if ( searchArticleField( queryString, object_name ) ) {
                        int object_id = rs.getInt( "id" );
                        ArticleListItem listItem = new ArticleListItem( ArticleType.OBJECT, object_id, object_name );
                        listItems.add( listItem );
                    }
                }
                ConnectionManager.closeConnection();
            }
        }
        catch ( SQLException ex ) {
            ex.printStackTrace();
        }
        catch ( ClassNotFoundException ex ) {
            ex.printStackTrace();
        }
        
        return listItems;
    }
    
    // Runs a query string against a field by comparing each word in the query string against each word in
    // the field. If any two words match, the search returns true. If no matches are found, it returns false.
    private boolean searchArticleField( String query, String field ) {
        String q = query.toLowerCase();
        String f = field.toLowerCase();
        
        if ( q.compareTo( "" ) != 0 ) {
            String[] keyWords = q.split( "\\s+" );
            
            for ( String keyWord : keyWords ) {
                for ( String word : f.split( "\\s+" ) ) {
                    if ( keyWord.compareTo( word ) == 0 )
                        return true;
                }
            }
            
            return false;
        }
        
        return true;
    }
}
